package cc.rengu.igas.route.core.service.trans;

import cc.rengu.igas.route.common.constant.SmartRouteParamConstant;
import cc.rengu.igas.route.common.dao.FinanceTxnRouteCustomMapper;
import cc.rengu.igas.route.common.dao.impl.FinanceTxnRouteCustomMapperImpl;
import cc.rengu.igas.route.common.enums.RouteTxnNumEnum;
import cc.rengu.igas.route.common.enums.SmartRouteRspEnums;
import cc.rengu.igas.route.common.util.IPv4Util;
import cc.rengu.igas.route.core.helper.RouterHelper;
import cc.rengu.igas.route.core.model.CompleteRouteInfoBean;
import cc.rengu.igas.route.core.model.ProdInfoBean;
import cc.rengu.igas.route.core.model.RouterReq;
import cc.rengu.igas.route.core.realize.Router;
import cc.rengu.igas.route.core.realize.payment.DstChannelPaymentService;
import cc.rengu.igas.route.facade.base.Header;
import cc.rengu.igas.route.facade.request.IntelligencePaymentRequest;
import cc.rengu.igas.route.facade.response.IntelligencePaymentResponse;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.RespCodeService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.RespCodeServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.List;


/**
 * 对外收款
 *
 * @author lizhangtao
 * @version 1.0
 * @date 2020/5/8
 */
public class IntelligencePaymentService extends RadpService {

    /**
     * Biz init int.
     *
     * @param s the s
     * @return the int
     */
    @Override
    protected int bizInit(String s) {
        return 0;
    }

    /**
     * Biz process int.
     *
     * @param s the s
     * @param i the
     * @return the int
     */
    @Override
    protected int bizProcess(String s, int i) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            IntelligencePaymentRequest intelligencePaymentRequest = new IntelligencePaymentRequest();
            //将xml树上值映射到request
            ConvertUtil.convertOutput(intelligencePaymentRequest);
            if (StringUtil.isEmptyOrNull(intelligencePaymentRequest.getFrontChannelId())) {
                rglog.error("必须上送前置渠道标志[frontChannelId]");
                throw new BizException(SmartRouteRspEnums.MSG_VALID_CHECK_ERROR.getRespCode(), SmartRouteRspEnums.MSG_VALID_CHECK_ERROR.getRespDesc());
            }

            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID, intelligencePaymentRequest.getHeader().getSrcSysId());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM, intelligencePaymentRequest.getHeader().getTraceNo());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TRANS_TIME, intelligencePaymentRequest.getHeader().getTransTime());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TRANS_DATE, intelligencePaymentRequest.getHeader().getTransDate());

            String sysSeqNum = null;
            //将报文体中金额，币种字段转换映射到xml树中（登记金融类交易流水表时需要）
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.ORDER_AMT, intelligencePaymentRequest.getTxnAmt());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.ORDER_CCY, intelligencePaymentRequest.getTxnCrcyCode());
            //处理附加信息
            if (!StringUtil.isEmptyOrNull(intelligencePaymentRequest.getAdditionInfo())) {
                JSONObject jsonObject = JSONObject.parseObject(intelligencePaymentRequest.getAdditionInfo());
                jsonObject.forEach((key, value) -> {
                    try {
                        xmlTreeUtil.setXmlTreeStringValue(key, (String) value);
                    } catch (Exception e) {
                        rglog.error(e.getMessage());
                    }
                });
                sysSeqNum = (String) jsonObject.get(TreeNodeConstant.SYS_SEQ_NUM);
            }
            if (StringUtil.isEmptyOrNull(sysSeqNum)) {
                rglog.error("COPS未上送系统内部流水号");
                throw new BizException(SmartRouteRspEnums.TRANS_FAIL.getRespCode(), SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            }
            IntelligencePaymentResponse intelligencePaymentResponse = new IntelligencePaymentResponse();
            intelligencePaymentResponse.setHeader(intelligencePaymentRequest.getHeader());
            //判断上送信息有无通道产品编码，有则直接根据通道调用对应支付通道
            String dstChannelId;
            String dstChannelTxnNum;
            String dstChannelTxnImplClassName;
            if (!StringUtil.isEmptyOrNull(intelligencePaymentRequest.getDstChannelId())) {
                //通过通道标识与通道交易码查询系统参数表
                dstChannelId = intelligencePaymentRequest.getDstChannelId();
                RouteTxnNumEnum routeTxnNumEnum = RouteTxnNumEnum.getInstance(intelligencePaymentRequest.getHeader().getTxnNum());
                if (null == routeTxnNumEnum) {
                    throw new BizException(SmartRouteRspEnums.NO_AUTH_ERROR.getRespCode(), SmartRouteRspEnums.NO_AUTH_ERROR.getRespDesc());
                }
                CompleteRouteInfoBean completeRouteInfoBean = RouterHelper.getCompleteRouteInfoBean(intelligencePaymentRequest.getHeader().getInstId(),
                        intelligencePaymentRequest.getHeader().getTxnNum(), routeTxnNumEnum.getTxnGroup(), dstChannelId, rglog);
                dstChannelTxnImplClassName = completeRouteInfoBean.getDstChannelTxnImplClassName();
                dstChannelTxnNum = completeRouteInfoBean.getDstTxnAuthCfg().getChannelTxn();
            } else {
                //区分本他行
                SysParamService sysParamService = new SysParamServiceImpl();
                SysParam corporationOrgCodeParam = sysParamService.getSysParamInfo(
                        intelligencePaymentRequest.getHeader().getInstId(), SmartRouteParamConstant.OPMS_SYS_PARAM, SmartRouteParamConstant.CORPORATION_ORG_CODE);
                if (null == corporationOrgCodeParam || AppParamConstant.NO.equals(corporationOrgCodeParam.getParamStatus())) {
                    rglog.info("法人行机构编码未配置或配置失效,instId:<{}>", intelligencePaymentRequest.getHeader().getInstId());
                    throw new BizException(SmartRouteRspEnums.CONFIG_ERROR.getRespCode(), SmartRouteRspEnums.CONFIG_ERROR.getRespDesc());
                }
                if (intelligencePaymentRequest.getPayerInfo().getAcctNo().substring(0, SmartRouteParamConstant.INT_FOUR).
                        equals(corporationOrgCodeParam.getParamValue().substring(0, SmartRouteParamConstant.INT_FOUR))) {
                    //TODO 本行卡则进行村镇母行汇划 本行借记
                    dstChannelId = SmartRouteParamConstant.ESB;
                    RouteTxnNumEnum routeTxnNumEnum = RouteTxnNumEnum.getInstance(intelligencePaymentRequest.getHeader().getTxnNum());
                    if (null == routeTxnNumEnum) {
                        throw new BizException(SmartRouteRspEnums.NO_AUTH_ERROR.getRespCode(), SmartRouteRspEnums.NO_AUTH_ERROR.getRespDesc());
                    }
                    CompleteRouteInfoBean completeRouteInfoBean = RouterHelper.getCompleteRouteInfoBean(intelligencePaymentRequest.getHeader().getInstId(),
                            intelligencePaymentRequest.getHeader().getTxnNum(), routeTxnNumEnum.getTxnGroup(), dstChannelId, rglog);
                    dstChannelTxnImplClassName = completeRouteInfoBean.getDstChannelTxnImplClassName();
                    dstChannelTxnNum = completeRouteInfoBean.getDstTxnAuthCfg().getChannelTxn();
                }
                //他行卡调用智能路由得到通道标识列表
                else {
                    //构建智能路由输入参数
                    RouterReq routerReq = new RouterReq();
                    routerReq.setInstId(intelligencePaymentRequest.getHeader().getInstId());
                    routerReq.setTransChanlId(intelligencePaymentRequest.getHeader().getChanlId());
                    routerReq.setTxnGroup(RouteTxnNumEnum.PAYMENT.getTxnGroup());
                    routerReq.setTransAmt(intelligencePaymentRequest.getTxnAmt());
                    routerReq.setBizCode(intelligencePaymentRequest.getBizCode());
                    routerReq.setTxnNum(intelligencePaymentRequest.getHeader().getTxnNum());
                    routerReq.setSrcSysId(intelligencePaymentRequest.getHeader().getSrcSysId());
                    routerReq.setPayerInfo(intelligencePaymentRequest.getPayerInfo());
                    routerReq.setPayeeInfo(intelligencePaymentRequest.getPayeeInfo());
                    //调用智能路由
                    Router router = new Router();
                    List<ProdInfoBean> listProdInfo = router.choice(routerReq);
                    //设置支付方式
                    if (null == listProdInfo || listProdInfo.isEmpty()) {
                        rglog.error("调用智能路由未找到通道");
                        throw new BizException(SmartRouteRspEnums.NO_AVAILABLE_DST_CHANNEL_ERROR.getRespCode(),
                                SmartRouteRspEnums.NO_AVAILABLE_DST_CHANNEL_ERROR.getRespDesc());
                    }
                    //默认取第一条优先级最高通道
                    dstChannelId = listProdInfo.get(0).getDstChannelId();
                    dstChannelTxnNum = listProdInfo.get(0).getDstChannelTxnNum();
                    dstChannelTxnImplClassName = listProdInfo.get(0).getDstChannelTxnImplClassName();
                }
            }
            if (StringUtil.isEmptyOrNull(dstChannelId)) {
                rglog.error("机构<instid:{}>，渠道交易<txnNum:{}>，请求系统<{}>, 渠道<{}>未找到系统参数配置",
                        intelligencePaymentRequest.getHeader().getInstId(), intelligencePaymentRequest.getHeader().getTxnNum(),
                        intelligencePaymentRequest.getHeader().getSrcSysId(), intelligencePaymentRequest.getHeader().getChanlId());
                throw new BizException(SmartRouteRspEnums.NO_AVAILABLE_DST_CHANNEL_ERROR.getRespCode(), SmartRouteRspEnums.NO_AVAILABLE_DST_CHANNEL_ERROR.getRespDesc());
            }
            intelligencePaymentRequest.setDstChannelId(dstChannelId);
            //更新流水表dev_brand记录通道
            FinanceTxnRouteCustomMapper financeTxnMapper = new FinanceTxnRouteCustomMapperImpl();
            financeTxnMapper.updDevBrandByPriKey(intelligencePaymentRequest.getHeader().getInstId(), sysSeqNum, dstChannelId);
            //根据通道标识，通道交易码查询系统参数表获取对应实现类

            //反射获取对应服务实例
            Class c = Class.forName(dstChannelTxnImplClassName);
            DstChannelPaymentService dstChannelPaymentService = (DstChannelPaymentService) c.newInstance();

            //1. 登记订单
            String dateTime23 = DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS");
            String dateTime14 = DateUtil.dateStringFormatConvert(dateTime23, "yyyy-MM-dd HH:mm:ss.SSS", "yyyyMMddHHmmss");
            OrderServiceImpl orderService = new OrderServiceImpl();
            UserOrderInfo userOrderInfo = initUserOrderInfo(intelligencePaymentRequest, sysSeqNum, dateTime14, dateTime23);
            List<MchntOrderInfo> mchntOrderInfos = initMchntOrderInfo(intelligencePaymentRequest, sysSeqNum, dateTime14, dateTime23);
            PayOrderInfo payOrderInfo = initPayOrderInfo(intelligencePaymentRequest, sysSeqNum, dstChannelTxnNum, dstChannelPaymentService.getReconKey(intelligencePaymentRequest), dateTime14, dateTime23);
            if (!orderService.registerOrderInfo(userOrderInfo, mchntOrderInfos, payOrderInfo)) {
                intelligencePaymentResponse.setRespCode(OltpRpcdEnum.REGISTER_TRANS_LOG_ERROR.getRespCode());
                intelligencePaymentResponse.setRespDesc(OltpRpcdEnum.REGISTER_TRANS_LOG_ERROR.getRespDesc());
                throw new BizException(OltpRpcdEnum.REGISTER_TRANS_LOG_ERROR);
            }

            //通道压力+1
            boolean isIncrSucc = true;
            String keyStress = SmartRouteParamConstant.ROUTE_DATA_ALL_STRESS + ":" + AppParamConstant.DEFAULT_INSTID + ":" + dstChannelId;
            try {
                RedisUtil.onceIncr(keyStress);
            } catch (Exception e) {
                rglog.warn(cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                isIncrSucc = false;
            }
            //通道交易总笔数
            boolean isIncrSuccTotalCount = true;
            String keyTotalCount = SmartRouteParamConstant.ROUTE_DATA_ALL_TOTAL_COUNT + ":" + AppParamConstant.DEFAULT_INSTID + ":" + dstChannelId;
            try {
                RedisUtil.onceIncr(keyTotalCount);
            } catch (Exception e) {
                rglog.warn(cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                isIncrSuccTotalCount = false;
            }
            IntelligencePaymentResponse intelligencePaymentResponseTmp = null;
            long channelStartTime = DateUtil.getCurrentTimeStamp();
            try {
                //调用通道支付
                intelligencePaymentResponseTmp = dstChannelPaymentService.payment(intelligencePaymentRequest);
            } finally {
                //调用通道的结束,设置通道耗时
                long channelEndTime = DateUtil.getCurrentTimeStamp();
                String timeCost = Long.valueOf(channelEndTime - channelStartTime).toString();
                String time13 = DateUtil.getCurrentDate() + DateUtil.getCurrentTime().substring(0, 5);
                String redisKey = AppParamConstant.DEFAULT_INSTID + ":" + dstChannelId;
                String nodeKey = redisKey + ":" + IPv4Util.ipv4Address;
                String transTimeKey = SmartRouteParamConstant.ROUTE_DATA_ALL_TIMECOST + ":" + redisKey + ":" + time13;
                String transTimeNodeKey = SmartRouteParamConstant.ROUTE_DATA_ALL_TIMECOST + ":" + nodeKey + ":" + time13;
                List<String> transTimeSplitList = RedisUtil.getListRange(transTimeKey, 0, 1);
                RedisUtil.onceRightPush(transTimeKey, timeCost);
                RedisUtil.onceRightPush(transTimeNodeKey, timeCost);
                if (null == transTimeSplitList || transTimeSplitList.isEmpty()) {
                    RedisUtil.onceExpire(transTimeKey, 300);
                    RedisUtil.onceExpire(transTimeNodeKey, 300);
                }
                //通道调用成功，redis计数器自减1(通道压力减少1)
                try {
                    if (isIncrSucc) {
                        RedisUtil.onceDecr(keyStress);
                    }
                } catch (Exception e) {
                    rglog.warn("通道<{}>压力统计redis计数器压力值-1异常{}", dstChannelId, cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                }
                //再次尝试总笔数+1
                try {
                    if (isIncrSuccTotalCount) {
                        RedisUtil.onceIncr(keyTotalCount);
                    }
                } catch (Exception e) {
                    rglog.warn("再次尝试通道<{}>交易总比数统计redis计数器+1异常{}", dstChannelId, cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                }
            }

            //设置返回值
            intelligencePaymentResponse.setDstChannelId(dstChannelId);
            intelligencePaymentResponse.setRespCode(intelligencePaymentResponseTmp.getRespCode());
            intelligencePaymentResponse.setRespDesc(intelligencePaymentResponseTmp.getRespDesc());

            //转换应答码状态
            RespCodeService respCodeService = new RespCodeServiceImpl();
            BizResponse<IntelligencePaymentResponse> response = new BizResponse<IntelligencePaymentResponse>();
            response.setResult(intelligencePaymentResponse);
            response.setRespCode(intelligencePaymentResponse.getRespCode());
            response.setRespDesc(intelligencePaymentResponse.getRespDesc());
            response.setRspSysId(intelligencePaymentResponse.getDstChannelId());
            //对于不能同步返回业务结果的通道，实现时一定要注意将受理成功的应答码对应的结果配置成处理中（即交易未知）
            TransStatusEnum transStatusEnum = respCodeService.transferRespCode(response.getRspSysId(), response.getRespCode(), response.getRespDesc());
            xmlTreeUtil.deleteXmlTreeNode("status");
            response.setTransStatus(transStatusEnum);
            if (TransStatusEnum.TRANS_SUCC.getStatus().equals(response.getTransStatus().getStatus())) {
                //成功
                intelligencePaymentResponse.setStatus("0");
                rglog.info("交易成功");
            } else if (TransStatusEnum.TRANS_INIT.getStatus().equals(response.getTransStatus().getStatus()) ||
                    TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(response.getTransStatus().getStatus())) {
                //未知
                intelligencePaymentResponse.setStatus("2");
                rglog.info("交易未知");
            } else {
                //失败
                intelligencePaymentResponse.setStatus("1");
                rglog.info("交易失败");
            }
            ConvertUtil.convertInput(intelligencePaymentResponse);
            //未知不更新订单状态（目前所有代收付通道都为非实时返回代收付结果，进入不到）
            if (!TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(transStatusEnum.getStatus()) && !TransStatusEnum.TRANS_INIT.getStatus().equals(transStatusEnum.getStatus())) {
                response.setTransStatus(transStatusEnum);
                if (!orderService.updateOrderInfo(updUserOrderInfo(userOrderInfo, response, dateTime23),
                        updMchntOrderInfo(mchntOrderInfos.get(0), response, dateTime23),
                        updPayOrderInfo(payOrderInfo, response, dateTime23))) {
                    rglog.error("智能路由代收更新订单失败记录应答信息到日志:");
                    rglog.error(JSON.toJSONString(response));
                }
            }
            //只统计明确成功（目前所有代收付通道都为非实时返回代收付结果，进入不到）
            if (TransStatusEnum.TRANS_SUCC.getStatus().equals(transStatusEnum.getStatus())) {
                RouterHelper.statisAmtLimit(intelligencePaymentRequest.getHeader().getInstId(), intelligencePaymentRequest.getHeader().getTxnNum(),
                        dstChannelTxnNum, dstChannelId, intelligencePaymentRequest.getPayeeInfo().getAcctType(), intelligencePaymentRequest.getTxnAmt(), rglog);
                String keySuccCount = SmartRouteParamConstant.ROUTE_DATA_ALL_SUCC_COUNT + ":" + AppParamConstant.DEFAULT_INSTID + ":" + dstChannelId;
                try {
                    RedisUtil.onceIncr(keySuccCount);
                } catch (Exception e) {
                    rglog.warn("通道<{}>成功交易总比数统计redis计数器+1异常{}", dstChannelId, cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                }
            }
        } catch (BizException e) {
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, e.getCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(cc.rengu.utility.base.StringUtil.ExceptionToString(e1));
            }
        } catch (Exception e) {
            rglog.error(cc.rengu.utility.base.StringUtil.ExceptionToString(e));
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, SmartRouteRspEnums.TRANS_FAIL.getRespCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            } catch (Exception e1) {
                rglog.error(cc.rengu.utility.base.StringUtil.ExceptionToString(e));
            }
        }
        return 0;
    }

    /**
     * Biz terminate int.
     *
     * @param s the s
     * @return the int
     */
    @Override
    protected int bizTerminate(String s) {
        return 0;
    }

    private UserOrderInfo initUserOrderInfo(IntelligencePaymentRequest paymentRequest, String sysSeqNum, String dateTime14, String dateTime23) throws Exception {
        UserOrderInfo userOrderInfo = new UserOrderInfo();
        Header header = paymentRequest.getHeader();
        userOrderInfo.setInstId(header.getInstId());
        userOrderInfo.setTxnNum(header.getTxnNum());
        userOrderInfo.setOrderDesc(StringUtil.isEmptyOrNull(paymentRequest.getPostscript()) ? "智能路由代收交易" : paymentRequest.getPostscript());
        userOrderInfo.setRealDiscountAmt("0.000");
        userOrderInfo.setBizStatus(BizStatusEnum.INIT.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        userOrderInfo.setMsgSrcId(header.getSrcSysId());
        userOrderInfo.setTransChannelId(header.getChanlId());
        userOrderInfo.setFrontSeqNum(header.getTraceNo());
        userOrderInfo.setMchntOrderId(sysSeqNum);
        userOrderInfo.setSysSeqNum(sysSeqNum);
        userOrderInfo.setGroupMchntNo(paymentRequest.getMchntNo());
//        userOrderInfo.setOrderUrl();
//        userOrderInfo.setOrigSysSeqNum();
        userOrderInfo.setTxnDate(header.getTransDate());
        userOrderInfo.setUserId(paymentRequest.getPayerInfo().getAcctNo());
        userOrderInfo.setBizType(header.getBizType());
//        userOrderInfo.setDiscountInfo();
//        userOrderInfo.setFrontBackUrl();
        userOrderInfo.setTxnTime(header.getTransTime());
        userOrderInfo.setRealPayAmt(paymentRequest.getTxnAmt());
//        userOrderInfo.setRealDiscountAmt();
//        userOrderInfo.setOrigTxnDate();
        //消费
        userOrderInfo.setOrderType("10");
        userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        userOrderInfo.setOrderCreateTime(dateTime14);
        userOrderInfo.setOrderExpiryTime(DateUtil.getPrevioustimes(-60L, "yyyyMMddHHmmss"));
        userOrderInfo.setOrderCcy(paymentRequest.getTxnCrcyCode());
        userOrderInfo.setOrderAmt(paymentRequest.getTxnAmt());
//        userOrderInfo.setNotifyBackUrl();
        userOrderInfo.setNeedPayAmt(paymentRequest.getTxnAmt());
        userOrderInfo.setCreateTime(dateTime23);
//        userOrderInfo.setUpdateTime();
        return userOrderInfo;
    }

    private List<MchntOrderInfo> initMchntOrderInfo(IntelligencePaymentRequest paymentRequest, String sysSeqNum, String dateTime14, String dateTime23) throws Exception {
        MchntOrderInfo mchntOrderInfo = new MchntOrderInfo();
        Header header = paymentRequest.getHeader();
        List<MchntOrderInfo> mchntOrderInfos = new ArrayList<>();
        mchntOrderInfos.add(mchntOrderInfo);
        mchntOrderInfo.setTxnTime(header.getTransTime());
        mchntOrderInfo.setTxnDate(header.getTransDate());
        mchntOrderInfo.setBizType(header.getBizType());
//        mchntOrderInfo.setChainMchntNo();
//        mchntOrderInfo.setRedeemCouponIds();
        mchntOrderInfo.setInstId(header.getInstId());
        mchntOrderInfo.setMchntNo(paymentRequest.getMchntNo());
        mchntOrderInfo.setSysSeqNum(sysSeqNum);
        mchntOrderInfo.setMchntOrderId(sysSeqNum);
//        mchntOrderInfo.setUpdateTime();
//        mchntOrderInfo.setOrigSysSeqNum();
        mchntOrderInfo.setAcqInstCode(StringUtil.isEmptyOrNull(paymentRequest.getPayeeInfo().getOpenBankNo()) ? header.getInstId() + "777777" : paymentRequest.getPayeeInfo().getOpenBankNo());
        mchntOrderInfo.setBizProdCode("05");
//        mchntOrderInfo.setBizSceneType();
        mchntOrderInfo.setBizStatus(BizStatusEnum.INIT.getStatus());
//        mchntOrderInfo.setVirtualAcctBalance();
        //虚拟的收银员
        mchntOrderInfo.setUserId("ROUTE_VIRTUAL_TELLER");
        mchntOrderInfo.setTxnNum(header.getTxnNum());
        mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
//        mchntOrderInfo.setTermType();
//        mchntOrderInfo.setTermNo();
//        mchntOrderInfo.setRowno();
//        mchntOrderInfo.setRefundFee();
//        mchntOrderInfo.setRefundAmt();
//        mchntOrderInfo.setRealSettleType();
//        mchntOrderInfo.setRealSettleStatus();
        //非实时清算
        mchntOrderInfo.setRealSettleFlag("N");
//        mchntOrderInfo.setRealMchntFee();
//        mchntOrderInfo.setOrigTxnDate();
        mchntOrderInfo.setRealSettleAmt(paymentRequest.getTxnAmt());
//        mchntOrderInfo.setOrderDiscountAmt();
        mchntOrderInfo.setOrderDesc(StringUtil.isEmptyOrNull(paymentRequest.getPostscript()) ? "智能路由代收交易" : paymentRequest.getPostscript());
        mchntOrderInfo.setOrderCcy(paymentRequest.getTxnCrcyCode());
        mchntOrderInfo.setOrderAmt(paymentRequest.getTxnAmt());
//        mchntOrderInfo.setMchntSettleAmt();
        mchntOrderInfo.setMchntName(paymentRequest.getMchntName());
//        mchntOrderInfo.setMchntFee();
//        mchntOrderInfo.setMchntDiscountFee();
        //MCC
        mchntOrderInfo.setIndustryType("4816");
//        mchntOrderInfo.setFeeRate();
//        mchntOrderInfo.setFeeInputMode();
//        mchntOrderInfo.setFeeFixedAmt();
//        mchntOrderInfo.setFeeCappingAmt();
//        mchntOrderInfo.setCustomerMarketAmt();
        mchntOrderInfo.setCreateTime(dateTime23);
        return mchntOrderInfos;
    }

    private PayOrderInfo initPayOrderInfo(IntelligencePaymentRequest paymentRequest, String sysSeqNum, String dstChannelTxnNum, String reconKey, String dateTime14, String dateTime23) throws Exception {
        PayOrderInfo payOrderInfo = new PayOrderInfo();
        Header header = paymentRequest.getHeader();
        payOrderInfo.setBizStatus(BizStatusEnum.INIT.getStatus());
        payOrderInfo.setBizType(header.getBizType());
        payOrderInfo.setChannelDiscountAmt("0.00");
        payOrderInfo.setSysSeqNum(sysSeqNum);
//        payOrderInfo.setChannelFee();
//        payOrderInfo.setChannelOrderId();
        payOrderInfo.setChannelReconKey(reconKey);
//        payOrderInfo.setChannelSeqNum();
        payOrderInfo.setCreateTime(dateTime23);
//        payOrderInfo.setCustomerFee();
        payOrderInfo.setDstCallIndex("0");
        payOrderInfo.setDstTxnNum(dstChannelTxnNum);
        payOrderInfo.setInstId(header.getInstId());
        payOrderInfo.setIssInstCode(paymentRequest.getPayeeInfo().getOpenBankNo());
        payOrderInfo.setMchntNo(paymentRequest.getMchntNo());
        payOrderInfo.setMchntOrderId(sysSeqNum);
        payOrderInfo.setMsgDstId(paymentRequest.getDstChannelId());
        //由DstChannelType存储实际的通道产品（UPAC则存储CT?? PT??）
        payOrderInfo.setDstChannelType("-");
        payOrderInfo.setOrderAmt(paymentRequest.getTxnAmt());
        payOrderInfo.setOrderCcy(paymentRequest.getTxnCrcyCode());
        payOrderInfo.setOrderExpiryTime(DateUtil.getPrevioustimes(-60L, "yyyyMMddHHmmss"));
//        payOrderInfo.setOrigSysSeqNum();
//        payOrderInfo.setOrigTxnDate();
        payOrderInfo.setPayeeAcctInfo(paymentRequest.getPayeeInfo().getAcctNo());
        payOrderInfo.setPayeeAcctType(paymentRequest.getPayeeInfo().getAcctType());
        payOrderInfo.setPayeeRemark(paymentRequest.getPostscript());
        payOrderInfo.setPayerAcctInfo(paymentRequest.getPayerInfo().getAcctNo());
        payOrderInfo.setPayerAcctType(paymentRequest.getPayerInfo().getAcctType());
//        payOrderInfo.setPayerRemark();
        if ("IGAS".equals(paymentRequest.getDstChannelId())) {
            payOrderInfo.setPayType(PayTypeEnum.OTHER.getPayType());
        } else if ("ESB".equals(paymentRequest.getDstChannelId())) {
            payOrderInfo.setPayType(PayTypeEnum.BANK_CARD.getPayType());
        } else {
            payOrderInfo.setPayType(PayTypeEnum.OTHER_BANK_CARD.getPayType());
        }
        payOrderInfo.setRealPayAmt(paymentRequest.getTxnAmt());
        payOrderInfo.setRemark1(paymentRequest.getBizCode());
//        payOrderInfo.setRemark2();
//        payOrderInfo.setRemark3();
//        payOrderInfo.setRespCode();
//        payOrderInfo.setRespDesc();
//        payOrderInfo.setRowno();
//        payOrderInfo.setSettleDate();
//        payOrderInfo.setTransBatchNo();
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
//        payOrderInfo.setTxnAuthCode();
        payOrderInfo.setTxnDate(header.getTransDate());
        payOrderInfo.setTxnNum(header.getTxnNum());
        payOrderInfo.setTxnTime(header.getTransTime());
//        payOrderInfo.setUpdateTime();
        payOrderInfo.setUserId("ROUTE_VIRTUAL_TELLER");
        return payOrderInfo;
    }

    private UserOrderInfo updUserOrderInfo(UserOrderInfo userOrderInfo, BizResponse<IntelligencePaymentResponse> response, String dateTime23) throws Exception {
        if (TransStatusEnum.TRANS_SUCC.getStatus().equals(response.getTransStatus().getStatus())) {
            userOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
        } else if (TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(response.getTransStatus().getStatus())) {
            userOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
            userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        } else if (TransStatusEnum.SYSTEM_REJECT.getStatus().equals(response.getTransStatus().getStatus())) {
            userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            userOrderInfo.setOrderStatus(OrderStatusEnum.CLOSE.getStatus());
        }/*else if(TransStatusEnum.SYSTEM_REJECT.getStatus().equals(response.getTransStatus().getStatus()) ){
            userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            userOrderInfo.setOrderStatus(OrderStatusEnum.CLOSE.getStatus());
        }*/ else {
            userOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
            userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        }
        userOrderInfo.setTransStatus(response.getTransStatus().getStatus());
        userOrderInfo.setUpdateTime(dateTime23);
        return userOrderInfo;
    }

    private List<MchntOrderInfo> updMchntOrderInfo(MchntOrderInfo mchntOrderInfo, BizResponse<IntelligencePaymentResponse> response, String dateTime23) throws Exception {
        List<MchntOrderInfo> mchntOrderInfos = new ArrayList<>();
        mchntOrderInfos.add(mchntOrderInfo);
        if (TransStatusEnum.TRANS_SUCC.getStatus().equals(response.getTransStatus().getStatus())) {
            mchntOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
        } else if (TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(response.getTransStatus().getStatus())) {
            mchntOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        } else if (TransStatusEnum.SYSTEM_REJECT.getStatus().equals(response.getTransStatus().getStatus())) {
            mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        }/*else if(TransStatusEnum.SYSTEM_REJECT.getStatus().equals(response.getTransStatus().getStatus()) ){
            mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        }*/ else {
            mchntOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        }
        mchntOrderInfo.setTransStatus(response.getTransStatus().getStatus());
        mchntOrderInfo.setUpdateTime(dateTime23);
        return mchntOrderInfos;
    }

    private PayOrderInfo updPayOrderInfo(PayOrderInfo payOrderInfo, BizResponse<IntelligencePaymentResponse> response, String dateTime23) throws Exception {
        if (TransStatusEnum.TRANS_SUCC.getStatus().equals(response.getTransStatus().getStatus())) {
            payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
        } else if (TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(response.getTransStatus().getStatus())) {
            payOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        } else if (TransStatusEnum.SYSTEM_REJECT.getStatus().equals(response.getTransStatus().getStatus())) {
            payOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        }/*else if(TransStatusEnum.SYSTEM_REJECT.getStatus().equals(response.getTransStatus().getStatus()) ){
            payOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        }*/ else {
            payOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        }
        payOrderInfo.setTransStatus(response.getTransStatus().getStatus());
        //dstChannelType存储产品类型（全渠道CT01，PT01，CT??,PT??）
        if (!StringUtil.isEmptyOrNull(response.getResult().getAdditionInfo())) {
            if (StringUtil.isEmptyOrNull(response.getResult().getAdditionInfo())) {
                JSONObject jsonObject = JSON.parseObject(response.getResult().getAdditionInfo());
                payOrderInfo.setDstChannelType((String) jsonObject.get("dstChannelType"));
            }
        }
        payOrderInfo.setRespCode(response.getRespCode());
        payOrderInfo.setRespDesc(response.getRespDesc());
//        payOrderInfo.setRowno();
        payOrderInfo.setSettleDate(response.getResult().getSettleDate());
//        payOrderInfo.setTransBatchNo();
//        payOrderInfo.setTxnAuthCode();
        payOrderInfo.setUpdateTime(dateTime23);
        return payOrderInfo;
    }
}
